
#include "HYFaceDetectManager.h"
#include "hilog/log.h"
#include <cstddef>


#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0xFF00                 // 全局domain宏，标识业务领域
#define LOG_TAG "HYFaceDetectManager_TAG" // 全局tag宏，标识模块日志tag

HYFaceDetectManager::HYFaceDetectManager(std::string bundlepath) : session_(nullptr) {
    // 初始化InspireFace SDK
    char l_buf[1024] = {0};
    realpath(bundlepath.c_str(), l_buf);
    strcat(l_buf, "/Pikachu");
    std::string filepath = std::string(l_buf);

    HResult result = HFLaunchInspireFace(filepath.c_str());

    if (result != HSUCCEED) {
        OH_LOG_ERROR(LOG_APP, "Failed to launch InspireFace, error code: %d", result);
        return;
    }

    // 配置会话选项
    HOption option = HF_ENABLE_QUALITY | HF_ENABLE_FACE_RECOGNITION | HF_ENABLE_INTERACTION;
    HFDetectMode detMode = HF_DETECT_MODE_LIGHT_TRACK;
    HInt32 maxDetectNum = 20;
    HInt32 detectPixelLevel = 160;

    // 创建会话
    result = HFCreateInspireFaceSessionOptional(option, detMode, maxDetectNum, detectPixelLevel, 16, &session_);
    if (result != HSUCCEED) {
        OH_LOG_ERROR(LOG_APP, "Failed to create InspireFace session, error code: %d", result);
        return;
    }

    // 配置会话参数
    HFSessionSetTrackPreviewSize(session_, detectPixelLevel);
    HFSessionSetFilterMinimumFacePixelSize(session_, 4);
    HFSessionSetFaceDetectThreshold(session_, 0.5f);

    loadSourceSuccess_ = true;
}

HYFaceDetectManager::~HYFaceDetectManager() { releaseHYFaceDetectManager(); }
void HYFaceDetectManager::releaseHYFaceDetectManager() {
    // 释放InspireFace会话
    if (session_) {
        HResult ret = HFReleaseInspireFaceSession(session_);
        if (ret != HSUCCEED) {
            OH_LOG_ERROR(LOG_APP, "Release session 出错");
        }
        session_ = nullptr;
        ret = HFTerminateInspireFace();
        if (ret != HSUCCEED) {
            OH_LOG_ERROR(LOG_APP, "TerminateInspireFace 出错");
        }
    }

    loadSourceSuccess_ = false;
}

int8_t HYFaceDetectManager::detect(uint8_t *src, int srcwidth, int srcheight, int *faceNumber, float *facequality,
                                   float *facex, float *facey, float *facewidth, float *faceheight, float *faceroll,
                                   float *faceyaw, float *facepitch, int *faceshakeLeft, int *faceshakeRight,
                                   int *facejawOpen, int *faceheadRaise, int *faceBlink, int returnFaceImage,
                                   uint8_t **outRes, int *outImgWidth, int *outImgHeight) {
    if (loadSourceSuccess_ == true) {
        HFImageBitmapData imageBitmapData{0};
        imageBitmapData.channels = 3;
        imageBitmapData.width = (HInt32)srcwidth;
        imageBitmapData.height = (HInt32)srcheight;
        imageBitmapData.data = src;
        HFImageBitmap imageBitMap;
        HResult ret = HFCreateImageBitmap(&imageBitmapData, &imageBitMap);
        if (ret != HSUCCEED) {
            OH_LOG_ERROR(LOG_APP, "创建Bitmap失败");
            return -1;
        }
        HFImageStream imageHandle = {0};
        ret = HFCreateImageStreamFromImageBitmap(imageBitMap, HF_CAMERA_ROTATION_0, &imageHandle);
        if (ret != HSUCCEED) {
            OH_LOG_ERROR(LOG_APP, "创建ImageStream失败");

            ret = HFReleaseImageBitmap(imageBitMap);
            if (ret != HSUCCEED) {
                OH_LOG_ERROR(LOG_APP, "释放Bitmap失败");
            }
            return -1;
        }
        HFMultipleFaceData multipleFaceData = {0};
        ret = HFExecuteFaceTrack(session_, imageHandle, &multipleFaceData);
        if (ret != HSUCCEED) {
            OH_LOG_ERROR(LOG_APP, "HFExecuteFaceTrack失败");

            ret = HFReleaseImageBitmap(imageBitMap);
            if (ret != HSUCCEED) {
                OH_LOG_ERROR(LOG_APP, "释放bitmap失败");
            }

            ret = HFReleaseImageStream(imageHandle);
            if (ret != HSUCCEED) {
                OH_LOG_ERROR(LOG_APP, "释放image stream失败");
            }
            return -1;
        } else {

            HInt32 faceNum = multipleFaceData.detectedNum;
            OH_LOG_INFO(LOG_APP, "人脸数: %{public}d", faceNum);
            *faceNumber = faceNum;
            if (faceNum == 1) {
                if (multipleFaceData.rects != NULL) {
                    OH_LOG_INFO(LOG_APP, "face x:%{public}d,y:%{public}d,width:%{public}d,height:%{public}d",
                                multipleFaceData.rects->x, multipleFaceData.rects->y, multipleFaceData.rects->width,
                                multipleFaceData.rects->height);
                    *facex = multipleFaceData.rects->x;
                    *facey = multipleFaceData.rects->y;
                    *facewidth = multipleFaceData.rects->width;
                    *faceheight = multipleFaceData.rects->height;

                    HFFaceQualityConfidence faceQualityConfidence = {0};
                    ret = HFGetFaceQualityConfidence(session_, &faceQualityConfidence);
                    if (ret == HSUCCEED) {
                        if (faceQualityConfidence.num > 0 && faceQualityConfidence.confidence != NULL &&
                            *(faceQualityConfidence.confidence) > 0) {
                            OH_LOG_INFO(LOG_APP, "质量：%{public}.2f", *(faceQualityConfidence.confidence));
                            *facequality = *(faceQualityConfidence.confidence);
                        }
                    } else {
                        OH_LOG_ERROR(LOG_APP, "HFGetFaceQualityConfidence 出错");
                    }
                    if ((*facequality) > 0.4 && (*facex) > 0 && (*facey) > 0 && (*facex + *facewidth) < srcwidth &&
                        (*facey + *faceheight) < srcheight) {
                        ret = HFMultipleFacePipelineProcess(session_, imageHandle, &multipleFaceData,
                                                            {1, 0, 0, 0, 1, 0, 1, 0});

                        if (ret == HSUCCEED) {
                            HFFaceInteractionsActions faceInteractionsActions = {0};
                            ret = HFGetFaceInteractionActionsResult(session_, &faceInteractionsActions);
                            if (ret == HSUCCEED) {

                                if (faceInteractionsActions.shakeLeft != NULL &&
                                    faceInteractionsActions.shakeRight != NULL &&
                                    faceInteractionsActions.jawOpen != NULL &&
                                    faceInteractionsActions.headRaise != NULL &&
                                    faceInteractionsActions.blink != NULL && multipleFaceData.angles.yaw != NULL &&
                                    multipleFaceData.angles.pitch != NULL) {
                                    HInt32 shakeLeft = *(faceInteractionsActions.shakeLeft);
                                    HInt32 shakeRight = *(faceInteractionsActions.shakeRight);
                                    HInt32 jawOpen = *(faceInteractionsActions.jawOpen);
                                    HInt32 headRaise = *(faceInteractionsActions.headRaise);
                                    HInt32 blink = *(faceInteractionsActions.blink);
                                    HFloat yaw = *(multipleFaceData.angles.yaw);
                                    HFloat pitch = *(multipleFaceData.angles.pitch);
                                    HFloat roll = *(multipleFaceData.angles.roll);

                                    if (shakeLeft) {
                                        OH_LOG_INFO(LOG_APP, "动作：左摇头");
                                    }
                                    if (shakeRight) {
                                        OH_LOG_INFO(LOG_APP, "动作：右摇头");
                                    }
                                    if (jawOpen) {
                                        OH_LOG_INFO(LOG_APP, "动作：张嘴");
                                    }
                                    if (headRaise) {
                                        OH_LOG_INFO(LOG_APP, "动作：抬头");
                                    }
                                    if (blink) {
                                        OH_LOG_INFO(LOG_APP, "动作：眨眼");
                                    }
                                    *faceshakeLeft = shakeLeft;
                                    *faceshakeRight = shakeRight;
                                    *facejawOpen = jawOpen;
                                    *faceheadRaise = headRaise;
                                    *faceBlink = blink;
                                    *faceyaw = yaw;
                                    *facepitch = pitch;
                                    *faceroll = roll;
                                }
                                if (returnFaceImage == 1) {
                                    HFImageBitmap imageBitmap = {0};
                                    ret = HFFaceGetFaceAlignmentImage(session_, imageHandle, *(multipleFaceData.tokens),
                                                                      &imageBitmap);
                                    if (ret == HSUCCEED) {
                                        HFImageBitmapData imd = {0};
                                        ret = HFImageBitmapGetData(imageBitmap, &imd);
                                        if (ret == HSUCCEED) {
                                            uint8_t *rgbaData = nullptr;
                                            int result1 = BGRToRGBA(imd.data, imd.width, imd.height, &rgbaData);
                                            OH_LOG_INFO(LOG_APP, "结果：%{public}d，宽：%{public}d，高：%{public}d",
                                                        result1, imd.width, imd.height);
                                            if (result1 == 0) {
                                                *outRes = (uint8_t *)rgbaData;
                                                *outImgWidth = imd.width;
                                                *outImgHeight = imd.height;
                                            }
                                        }
                                        free(imd.data);
                                        imd.data = nullptr;
                                    }
                                }
                            } else {
                                OH_LOG_INFO(LOG_APP, "HFGetFaceInteractionActionsResult failed");
                            }

                        } else {
                            OH_LOG_ERROR(LOG_APP, "HFMultipleFacePipelineProcess 出错");
                        }
                    }
                }
            }


            ret = HFReleaseImageBitmap(imageBitMap);
            if (ret != HSUCCEED) {
                OH_LOG_ERROR(LOG_APP, "释放bitmap失败");
            }

            ret = HFReleaseImageStream(imageHandle);
            if (ret != HSUCCEED) {
                OH_LOG_ERROR(LOG_APP, "释放image stream失败");
            }
        }
        return 0;
    } else {
        return -1;
    }
}
int HYFaceDetectManager::BGRToRGBA(const uint8_t *bgrData, int width, int height, uint8_t **outRgbaData) {

    if (!bgrData || width <= 0 || height <= 0) {
        return -1; // 输入参数无效
    }

    int pixelCount = width * height;
    int rgbaSize = pixelCount * 4; // RGBA每像素4字节

    // 分配内存并检查
    *outRgbaData = (uint8_t *)malloc(rgbaSize);
    if (!*outRgbaData) {
        return -2; // 内存分配失败
    }

    uint8_t *rgba = *outRgbaData;
    const uint8_t *bgr = bgrData;

    size_t m = 0;
    size_t n = 0;
    uint8_t tem = 0;

    for (size_t i = 0; i < pixelCount; i++) {
        tem = bgr[n++]; // b
        m++;
        rgba[m++] = bgr[n++]; // g
        rgba[m++] = tem;
        rgba[m - 3] = bgr[n++]; // r
        rgba[m++] = 255;
    }

    return 0; // 成功
}
